package com.joinway.framework.admin.web.controller;

import java.io.File;

import org.apache.commons.io.FileUtils;
import org.apache.commons.io.FilenameUtils;
import org.hibernate.validator.constraints.NotBlank;
import org.jsondoc.core.annotation.Api;
import org.jsondoc.core.annotation.ApiBodyObject;
import org.jsondoc.core.annotation.ApiMethod;
import org.jsondoc.core.annotation.ApiQueryParam;
import org.jsondoc.core.annotation.ApiResponseObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import com.joinway.framework.admin.bean.form.ExportForm;
import com.joinway.framework.admin.bean.view.ExportView;
import com.joinway.framework.admin.bean.view.ImportView;
import com.joinway.framework.admin.bean.view.UploadView;
import com.joinway.framework.admin.core.service.file.FileConstants;
import com.joinway.framework.admin.core.service.file.FileManager;
import com.joinway.framework.admin.core.service.file.FileService;
import com.joinway.framework.admin.core.service.file.IFileRepository;
import com.joinway.framework.admin.core.utils.FileProcessUtils;
import com.joinway.framework.bean.logging.annotation.InputLog;
import com.joinway.framework.bean.logging.annotation.LogIgnore;
import com.joinway.framework.bean.logging.annotation.OutputLog;
import com.joinway.framework.bean.security.annotation.Security;
import com.joinway.framework.bean.type.Server;
import com.joinway.framework.core.controller.ExceptionController;
import com.joinway.framework.extension.utils.DataUtils;
import com.joinway.framework.support.input.annotation.Render;

@Api(name = "文件操作通用接口", description = "")
@RestController
@RequestMapping("file")
@Validated
@Security
public class FileController extends ExceptionController {
	private final static Logger log = LoggerFactory.getLogger(FileController.class);
	
	@Autowired FileService service;
	
	@ApiMethod(description="导出文件", produces=MediaType.APPLICATION_JSON_VALUE)
	@ApiResponseObject
	@RequestMapping(value="/export.json", method=RequestMethod.POST, produces=MediaType.APPLICATION_JSON_VALUE)
	@InputLog
	@OutputLog
	public ExportView export(
		@NotBlank @RequestParam("columns") @Render @ApiQueryParam(name="columns", description="导出列，格式：tableFieldName1,displayName1;tableFieldName2,displayName2;...;tableFieldNameN,displayName1N") String columns
		, @NotBlank @RequestParam("table") @Render @ApiQueryParam(name="table", description="导出表名，如loginUser") String table
		, @RequestParam(value="fileName",required=false,defaultValue="") @Render @ApiQueryParam(name="fileName", description="导出的文件名称") String fileName
		, @RequestParam(value="type",required=false,defaultValue="") @Render @ApiQueryParam(name="type", description="导出文件类型:xls,csv") String type
		, @RequestParam(value="query",required=false,defaultValue="") @Render @ApiQueryParam(name="query", description="json格式的查询sql") String query
		, @RequestParam(value="wysiwye",required=false,defaultValue="false") @ApiQueryParam(name="wysiwye", description="true-只导出可见列;false-导出全部数据") String wysiwye
		, @RequestParam(value="port",required=false,defaultValue="80") @ApiQueryParam(name="port", description="端口") int port
	) throws Exception {
		ExportForm form = new ExportForm();
		form.setColumns(columns);
		form.setTable(table);
		form.setFileName(fileName);
		form.setType(type);
		form.setQuery(query);
		form.setWysiwye(DataUtils.convertBool(wysiwye));
		form.setPort(port);
		
		return service.export(form);
	}
	
	@ApiMethod(description="上传文件", produces=MediaType.APPLICATION_JSON_VALUE)
	@ApiResponseObject
	@RequestMapping(value="/upload.json", method=RequestMethod.POST, produces=MediaType.APPLICATION_JSON_VALUE)
	@OutputLog
	public UploadView upload(@RequestParam("file") @ApiBodyObject MultipartFile file, @RequestParam(value="dir",required=false,defaultValue=FileConstants.FileDir.Upload) String dir) throws Exception {
		String url = uploadFile(file, dir, FileProcessUtils.getDefaultPageName() + "." + FilenameUtils.getExtension(file.getOriginalFilename()));
		
		UploadView view = new UploadView();
		view.setUrl(url);
		
		return view;
	}
	
	@ApiMethod(description="导入文件", produces=MediaType.APPLICATION_JSON_VALUE)
	@ApiResponseObject
	@RequestMapping(value="/import.json", method=RequestMethod.POST, produces=MediaType.APPLICATION_JSON_VALUE)
	@InputLog
	@OutputLog
	public ImportView imports(
		@LogIgnore @RequestParam("file") @ApiBodyObject MultipartFile file
		, @RequestParam("table") @Render @ApiQueryParam(name="table", description="导出表名，如loginUser") String table
		, @RequestParam("columnMap") @Render @ApiQueryParam(name="columnMap", description="导出列名映射,格式为:columnName:columnText,... 如:userId:用户编号") String columnMap
	) throws Exception {
		String path = FileConstants.FileDir.Upload;
		String fileName = FileProcessUtils.getDefaultPageName() + "." + FilenameUtils.getExtension(file.getOriginalFilename());
		uploadFile(file, path , fileName);
		
		String localPath = FileManager.getLocalPath(path, Server.Web);
		
		return service.imports(new File(localPath, fileName), table, columnMap);
	}

	String uploadFile(MultipartFile uploadFile, String path, String name) throws Exception {
		String url = FileManager.save(path, name, Server.Web, new IFileRepository<String>(){
			@Override
			public void save(String file, String context) throws Exception {
				FileUtils.writeByteArrayToFile(new File(file), uploadFile.getBytes());
			}
		});
		
		log.info("uploaded file {}/{}", path, name);
		
		return url;
	}
}

